# encoding: utf-8
from flask import (Blueprint,
                   views,
                   render_template,
                   request,
                   session,
                   url_for,
                   g,
                   abort)
from .forms import SignupForm,SigninFrom,AddPostFrom,AddCommentFrom
from utils import restful,safeutils
from exts import db
from .models import FrontUser
import config
from ..models import BannerModel,BoardModel,PostModel,CommentModel,HightLightPostModel
from .decorators import login_required
from flask_paginate import Pagination,get_page_parameter
from sqlalchemy import func


bp = Blueprint('front',__name__,)

@bp.route('/')
def index():
    board_id = request.args.get('db',type=int,default=None)
    banners = BannerModel.query.order_by(BannerModel.priority.desc()).limit(3)
    boards = BoardModel.query.all()
    page = request.args.get(get_page_parameter(),type=int,default=1)
    sort = request.args.get('st',type=int,default=1)
    start = (page-1)*config.PER_PAGE
    end = start + config.PER_PAGE
    posts = None
    total = 0

    query_obj = None
    if sort == 1:
        #按贴子发布时间创建
        query_obj = PostModel.query.order_by(PostModel.create_time.desc())
    elif sort == 2:
        #按照加精的时间倒叙排序
        query_obj = db.session.query(PostModel).outerjoin(HightLightPostModel).order_by(
            HightLightPostModel.create_time.desc(),PostModel.create_time.desc())
    elif sort == 3:
        #按点赞的数量排序，注在这里点还没做，跟按评论数量排序的编写是一样的。
        query_obj = PostModel.query.order_by(PostModel.create_time.desc())
    elif sort == 4:
        query_obj = db.session.query(PostModel).outerjoin(CommentModel).group_by(
            PostModel.id).order_by(func.count(CommentModel.id).desc(),PostModel.create_time.desc())
    if board_id:
        query_obj = query_obj.filter(PostModel.board_id==board_id)
        posts = query_obj.slice(start,end)
        total = query_obj.count()
    else:
        posts = query_obj.slice(start,end)
        total = query_obj.count()
    pagination = Pagination(bs_version=3,page=page,total=total,
    outer_window=1,inner_window=2)
    context={
        'banners':banners,
        'boards':boards,
        'posts':posts,
        'pagination':pagination,
        'current_board':board_id,
        'current_sort':sort
    }
    return render_template('front/front_index.html',**context)

@bp.route('/p<post_id>/')
def post_detail(post_id):
    post = PostModel.query.get(post_id)
    if not post:
        abort(404)
    return render_template('front/front_pdetail.html',post=post)

@bp.route('/acomment/',methods=['POST'])
@login_required
def add_comment():
    form = AddCommentFrom(request.form)
    if form.validate():
        content = form.content.data
        post_id = form.post_id.data
        post = PostModel.query.get(post_id)
        if post:
            comment = CommentModel(content=content)
            comment.post = post
            comment.author = g.front_user
            db.session.add(comment)
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error('没有这篇贴子！')
    else:
        return restful.params_error(form.get_error())



@bp.route('/apost/',methods=['GET','POST'])
@login_required
def apost():
    if request.method == 'GET':
        boards = BoardModel.query.all()
        return render_template('front/front_apost.html',boards=boards)
    else:
        form = AddPostFrom(request.form)
        if form.validate():
            title = form.title.data
            content = form.content.data
            board_id = form.board_id.data
            board = BoardModel.query.get(board_id)
            if not board:
                return restful.params_error(message='没有这个版块')
            post = PostModel(title=title,content=content)
            post.board = board
            post.author = g.front_user
            db.session.add(post)
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error(message=form.get_error())



class SingupVews(views.MethodView):
    def get(self):
        return_to = request.referrer
        if return_to and return_to != request.url and safeutils.is_safe_url(return_to):
            return render_template('front/front_signup.html',return_to=return_to)
        else:
            return render_template('front/front_signup.html')
    def post(self):
        form = SignupForm(request.form)
        if form.validate():
            telephone = form.telephone.data
            username = form.username.data
            password = form.password1.data
            user = FrontUser(telephone=telephone,username=username,password=password)
            db.session.add(user)
            db.session.commit()
            return restful.success()
        else:
            return restful.params_error(message=form.get_error())

class SigninVews(views.MethodView):
    def get(self):
        # request.referrer 是上一步的url
        return_to = request.referrer
        # 验证 return_to
        if return_to and return_to != request.url and return_to != \
            url_for('front.signin') and safeutils.is_safe_url(return_to):
            return render_template('front/front_signin.html',return_to = return_to)
        else:
            return render_template('front/front_signin.html')
    def post(self):
        # request.form是js表单请求，先对前端数据进行验证，再提取出来
        form = SigninFrom(request.form)
        if form.validate():
            telephone = form.telephone.data
            password = form.password.data
            remember = form.remember.data
            # 根据手机号码查找数据
            user = FrontUser.query.filter(FrontUser.telephone == telephone).first()
            # 验证用户及密码
            if user and user.check_password(password):
                session[config.FRONT_USER_ID] = user.id
                if remember:
                    session.permanent = True
                return restful.success()
            else:
                return restful.params_error(message='手机或密码错误！')
        else:
            return restful.params_error(message=form.get_error())





bp.add_url_rule('/signup/',view_func=SingupVews.as_view('signup'))
bp.add_url_rule('/signin/',view_func=SigninVews.as_view('signin'))